' *******************
' * Listing Two
' *******************
' * Global variables
' *******************

DEFDBL a, b, c, d, w, t
DEFINT i, j, k, n, s, o
DIM iwaveform% (255)
DIM a(1030)

' Main program entry point

n= 256                                        ' Number of points in FFT
size= 128
CALL init                                      ' Set up Initial screen

' Clear the data array before entering any values into the REAL (even indexes)
' portion of the array.

FOR i= 0 TO n*2
a(i)= 0
NEXT i

' EXAMPLE #1 - SQUARE WAVE
' This will generate a square wave as input, producing odd harmonics in the
' frequency spectrum. The waveform 1s entered to be symetrical around
' zero TIME as if it was a COS function.

rval= 1
FOR i= 0 TO n*2 STEP 2
IF( (i+32) MOD 64)= 0 THEN
rval= rval * -1
END IF
a(i)= rval
NEXT i

' EXAMPLE #2 - IMPULSE FUNCTION
' This will result in an example of an infinitely thin pulse in the time domain
' producing an infinite frequency response.
' The output in the frequency domain will be a line across the top
' of the output spectral display.

' a(2)= 1

' EXAMPLE #3 - FINITE IMPULSE FUNCTION
' This will result in a frequency spectrum which has some amount of energy
' at almost every frequency range.
' The phase of the frequency information will
' change from IN PHASE to OUT of PHASE in an oscillatlng pattern.

' FOR i= 2 TO 16 STEP 2
' a(i)= 1
' NEXT i

' EXAMPLE #4 - SINE WAVE
' This example will a sine wave at a single frequency, which will produce a
' single spectral output.
' By changing the value of sl you can see that a higher frequency will
' produce a spectral point, that is further away from the beginning of the the
' spectrum (D.C.).

' sl= 16
' wseg= 6.28319 / sl
' j= 1
' FOR i= 0 TO n*2 STEP 2
' wtemp= ((i/2) MOD sl) * wseg
' a(i)= COS(wtemp) *.1
' NEXT i










' ***********************************************************************************************
' Display the input waveform, call for the transformation between the time domain and the 
' frequency domain, and display the spectrum plot of the resulting frequencies.
' ***********************************************************************************************

CALL plotu(a(), n, 40)
CALL fft1(a(), n, 1)
CALL plotu(a(), n, 110)
PRINT "Click mouse Button to Exit."
WHILE MOUSE (0) <> 0
WEND    ' Clear mouse buffer
WHILE MOUSE (0) = 0
WEND    ' Await real mouse click
END

' **** end of main program

' *******************************
' * Subroutine: Init
' * Function  : Setup Program
' * Inputs    :
' *******************************
SUB init STATIC
CLS
PRINT PTAB(120);"Fast Fourier Transform Evaluation"
LINE(0,10)-(600,70),,b
LINE(0,40)-(600,40)
LOCATE 9,1
PRINT PTAB(220);"Input Waveform Data"
LINE(0,80)-(600,140),,b
LINE(0,110)-(600,110)
LOCATE 17,1
PRINT PTAB(220);"Output Spectral plot"
END SUB

' ***************************
' * Subroutine: FFT1
' * Function  : Performs Fast Fourier Transform
' * Inputs    : darray = data array in time or frequency
' *           : nn = Number of Data Points
' *           : isign = switch from forward or reverse transform
' ***************************
' * local integer variables
' *
' * ii, jj, n, mmax, m, j, i, istep
' *
' * local double variables
' * wtemp, wr, wpr, wpi, wi, theta, tempr, tempi

SUB fft1(darray(1), nn%, isign% ) STATIC
n= 2 * nn
j= 1

' ************************************************************************
' * Pre-weave butterfly operation is performed, to incoming complex array.
' ************************************************************************

FOR i= 1 TO n STEP 2
IF( j > i) THEN
tempr= darray(j)
tempi= darray(j+1)
darray(j)= darray(i)
darray(j+1)= darray(i+1)
darray(i)= tempr
darray(i+1)= tempi
END IF
m= n / 2
WHILE ( (m >=2) AND (j>m))
j= j - m
m= m / 2
WEND
j= j + m
NEXT i






' *
' * Top of secondary weave operation
' *

mmax= 2
WHILE ( n > mmax )

' *
' * Calculate fixed weighting coefficients
' *

istep= 2 * mmax
theta= 6.28318530717959# / (isign * mmax)
wpr= -2! * (SIN(.5 * theta) * SIN(.5 * theta))
wpi= SIN(theta)
wr= 1!
wi= 0!

' **********************************************************
' *
' * Secondary weave operation is performed on complex array, and results are multiplied by
' * coefficients.
' *
' **********************************************************

FOR  m= 1 TO mmax STEP 2
FOR i= m TO n STEP istep
j= i+ mmax
tempr= wr*darray(j)-wi*darray(j+1)
tempi= wr*darray(j+1)+wi*darray(j)
darray(j)= darray(i)-tempr
darray(j+1)= darray(i+1)-tempi
darray(i)= darray(i)+tempr
darray(i+1)= darray(i+1)+tempi
NEXT i

' *******************************
' * recalculate the coefficients
' *******************************

wtemp= wr
wr= wr*wpr-wi*wpi+wr
wi= wi*wpr+wtemp*wpi+wi
NEXT m
mmax= istep
WEND
END SUB

' ************
' * Subroutine: wplot
' * Function  : plot time domain data in waveform window
' * Inputs    :
' ************

SUB plotu(a(1),n%,offset%) STATIC

' * Find maximum value in data array for scaling factor to be applied to each
' * array element.

max= 0
FOR i= 2 TO n*2 STEP 2
IF ABS(a(i))> max THEN
max= ABS(a(i))
END IF
NEXT i
ascale= -30/max
LINE (1,a(2)*ascale+offset%)-(1,a(2)*ascale+offset%),3
FOR i= 2 TO (n)*2 STEP 2
LINE-(i,a(i)*ascale+offset%),3
NEXT i
END SUB       'end of subroutine wplot